# -*- coding: utf-8 -*-

"""
author : daichaoren
# 主要是关于云交易的新增接口
"""

# 根据用户id, 获得当前云交易的列表


import time
import datetime

from Database.models import *
from UPQuant import paging


def format_begin_end_date(date_tmp):
    if date_tmp is None:
        return '--'
    else:
        return date_tmp.strftime('%Y/%m/%d')

        # 获得用户的交易列表


def get_user_deal_list(request):
    try:
        user_id = request.session['username']
        queryset = UpQuantSimutradeStrategylist.objects.filter(userid=user_id)
        view_list = []

        for temp in queryset.values():

            deal = {'deal_name': temp['tradename'],
                    'deal_id': temp['tradeid'],
                    'begin_date': format_begin_end_date(temp['startdate']),
                    'end_date': format_begin_end_date(temp['enddate'])}
            # 删除的
            if temp['status'] == -1:
                continue
            elif temp['status'] == 1:
                deal['status'] = u'已终止'
            elif temp['status'] == 0:
                deal['status'] = u'运行中'
            else:
                deal['status'] = u'错误'

            # 收益率
            try:
                sum_info = UpSimutradeBktestSumInfo.objects.using('deal').get(tradeid=temp['tradeid'])
                deal['return'] = str(round(sum_info.totalreturn * 100, 2)) + '%'
                deal['max_drop_down'] = str(round(sum_info.maxdrewdown * 100, 2)) + '%'
            # 无结果
            except Exception as e:
                deal['return'] = '--'
                deal['max_drop_down'] = '--'

            view_list.append(deal)

        return view_list
    except Exception as e:
        print str(e)
        return []


# 用于用户新建交易的策略列表
def get_strategy_list_for_new(request):
    user_id = request.session.get('userId', None)
    strategy_list = []
    if user_id is None:
        return strategy_list

    queryset = UpQuantUserStrategyListInfo.objects.filter(userid=user_id).order_by('-createtime')
    for user in queryset.values():
        if user['state'] != 0:
            continue
        modify_date = user['modifytime'].strftime('%Y/%m/%d')
        modify_time = user['modifytime'].strftime('%H:%M:%S')
        strategy = {'strategy_name': user['name'], 'strategy_id': user['strategyid'],
                    'modify_date': modify_date, 'modify_time': modify_time}

        strategy_id = user['strategyid']
        queryset_t = UpQuantBktestSumInfo.objects.filter(strategyid=strategy_id).order_by('-versionid')
        strategy['num'] = len(queryset_t)
        strategy_child_list = []
        for strategy_ver in queryset_t.values():
            strategy_child = {'index': strategy_ver['versionid'], 'total_return': strategy_ver['totalreturn']}
            # 获得回测时间
            temp = UpQuantStrategyContex.objects.get(strategyid=strategy_id, versionid=strategy_ver['versionid'])
            back_test_date_time = temp.createtime
            back_test_date = back_test_date_time.strftime('%Y/%m/%d')
            strategy_child['back_test_date'] = back_test_date
            back_test_time = back_test_date_time.strftime('%H:%M:%S')
            strategy_child['back_test_time'] = back_test_time

            strategy_child_list.append(strategy_child)

        strategy['child_list'] = strategy_child_list

        strategy_list.append(strategy)

    return strategy_list


# 删除交易
def del_deal(request):
    del_list = eval(request.body).get('delete_list', [])

    # 删除
    query_set = UpQuantSimutradeStrategylist.objects.filter(tradeid__in=del_list)

    query_set.delete()

    return {'state': 0}


# 创建新的交易
def new_deal(request):
    try:
        user_id = request.session.get('userId', None)
        data_dict = eval(request.body)

        # 生成唯一的deal_id
        deal_id = data_dict['strategy_id'] + '_' + str(data_dict['version_id']) + '_' + str(time.time())
        query_set, state = UpQuantSimutradeStrategylist.objects.get_or_create(userid=user_id,
                                                                              tradeid=deal_id)
        query_set.tradename = data_dict['deal_name']
        query_set.strategyid = data_dict['strategy_id']
        query_set.versionid = int(data_dict['version_id'])
        query_set.startdate = datetime.date.today()
        query_set.initcash = int(data_dict['init_cash'])
        query_set.status = 0  # 运行状态
        query_set.save()

        # 添加当前交易的session
        request.session['deal_id'] = deal_id
        request.session['deal_name'] = data_dict['deal_name']

        return {'state': '0'}
    except Exception as e:
        return {'state': str(e)}


# 根据当前的strategy构建交易
def new_deal_this(request):
    try:
        user_id = request.session.get('userId', None)
        strategy_id = request.session.get('strategyId', None)
        version_id = request.session.get('versionId', None)
        data_dict = eval(request.body)

        # 生成唯一的deal_id
        deal_id = strategy_id + '_' + str(version_id) + '_' + str(time.time())
        query_set, state = UpQuantSimutradeStrategylist.objects.get_or_create(userid=user_id,
                                                                              tradeid=deal_id)
        query_set.tradename = data_dict['deal_name']
        query_set.strategyid = strategy_id
        query_set.versionid = int(version_id)
        query_set.startdate = datetime.date.today()
        query_set.initcash = int(data_dict['init_cash'])
        query_set.status = 0  # 运行状态
        query_set.save()

        # 添加当前交易的session
        request.session['deal_id'] = deal_id
        request.session['deal_name'] = data_dict['deal_name']

        return {'state': '0'}
    except Exception as e:
        return {'state': str(e)}


# 获得当前交易的策略代码
def get_strategy_code_for_deal(request):
    try:
        # 获得交易id
        user_id = request.session.get('userId', None)
        deal_id = request.session.get("deal_id", None)

        query_set = UpQuantSimutradeStrategylist.objects.get(userid=user_id, tradeid=deal_id)
        # 获得策略id
        context_query = UpQuantStrategyContex.objects.get(strategyid=query_set.strategyid,
                                                          versionid=query_set.versionid)

        return context_query.context
    except Exception as e:
        return str(e)


# 进入当前交易
def goto_deal(request):
    try:
        data_dict = eval(request.body)
        # 设置session
        request.session['deal_id'] = data_dict['deal_id']
        request.session['deal_name'] = data_dict['deal_name']

    except Exception as e:
        return str(e)


# 获得日志
def get_deal_log(request):
    deal_id = request.session.get("deal_id", None)
    query_set = UpSimutradeLoginfo.objects.filter(tradeid=deal_id).using('deal')
    log_list = []
    for log_str in query_set.values():
        temp_list = str(log_str['log']).split('\n')
        for temp_str in temp_list:
            if temp_str != '':
                log_list.append(temp_str)
    return log_list


# 获得历史持仓
def get_deal_position(request):
    deal_id = request.session.get("deal_id", None)
    index = int(request.POST['index'])
    query_set = UpSimutradePositioninfo.objects.filter(tradeid=deal_id).using('deal')
    temp_list = []
    for position in query_set.values():
        position_info = {'date': position['date'].strftime('%Y/%m/%d'), 'stock_code': position['stockcode'],
                         'stockName': position['stockname'], 'closePrice': position['close'],
                         'stockNum': position['quantity'],
                         'positionValue': position['marketvalue'], 'return': position['return_field'],
                         'totalValue': position['portfolio_value'], 'totalCash': abs(position['cash']),
                         'totalCommission': position['totalcost']}
        temp_list.append(position_info)

    return {'pageCount': paging.get_page_count(temp_list, 6),
            'index': index,
            'returnList': paging.get_page_list(index, temp_list, 6)}


# 获得交易详情
def get_deal_trade_info(request):
    deal_id = request.session.get("deal_id", None)
    query_set = UpSimutradeTradeinfo.objects.filter(tradeid=deal_id).using('deal')
    trade_list = []
    total_sell = 0.00
    total_buy = 0.00
    total_transaction = 0
    for trade in query_set.values():
        trade_info = {'date': trade['orderdate'].strftime('%Y/%m/%d'), 'time': trade['ordertime'].strftime('%H:%M:%S'),
                      'stock_code': trade['stockcode'],
                      'stock_name': trade['stockname'], 'order_count': abs(trade['ordercount']),
                      'price': trade['price'], 'order_state': trade['orderstate'],
                      'commission': trade['commission'], 'tax': trade['tax'],
                      'total_cost': trade['totalcost']}
        if trade['orderstate'] > 0:
            total_buy += trade['totalcost']
        else:
            total_sell += trade['totalcost']
        total_transaction += 1

        trade_list.append(trade_info)
    trade_detail = {'trade_list': trade_list, 'total_sell': round(total_sell, 2), 'total_buy': round(total_buy, 2),
                    'total_transaction': total_transaction}
    return trade_detail


# 获得当前策略是否在运行
def get_deal_strategy_status(request):
    try:
        user_id = request.session['userId']
        strategy_id = request.session['strategyId']
        version_id = request.session['versionId']

        query = UpQuantSimutradeStrategylist.objects.get(userid=user_id, strategyid=strategy_id, versionid=version_id)
        return {'state': query.status}
    except Exception as e:
        return {'state': -1}


def check_deal(request):
    try:
        # 设置session
        user_id = request.session['userId']
        strategy_id = request.session['strategyId']
        version_id = request.session['versionId']
        query = UpQuantSimutradeStrategylist.objects.get(userid=user_id, strategyid=strategy_id, versionid=version_id)
        request.session['deal_id'] = query.tradeid
        request.session['deal_name'] = query.tradename

    except Exception as e:
        return {'state': str(e)}
    return {'state': '0'}


# 获得当前交易的收益概况
def get_deal_back_test(request):
    back_test_info = {}
    try:
        deal_id = request.session['deal_id']
        # 运行状态
        state = UpQuantSimutradeStrategylist.objects.get(tradeid=deal_id)
        back_test_info['state'] = state.status
        back_test_info['begin_date'] = state.startdate.strftime('%Y/%m/%d')
        # 概要信息, 已终止就获取终止的时间
        if state.status == 1:
            back_test_info['update_date'] = state.enddate.strftime('%Y/%m/%d')
        # 没有终止，就获取最新的结果时间
        else:
            try:
                deal_info = UpSimutradeBktestSumInfo.objects.using('deal').get(tradeid=deal_id)
                back_test_info['update_date'] = deal_info.endtime.strftime('%Y/%m/%d')
            except Exception as e:
                back_test_info['market_value'] = 0
                back_test_info['cash'] = state.initcash
        back_test_info['update_time'] = '15:00'

        # 市值类相关消息
        market_info_list = UpSimutradePositioninfo.objects.using('deal').filter(tradeid=deal_id).order_by('-date')
        market_info = market_info_list.values()[0]
        back_test_info['market_value'] = market_info['portfolio_value']
        back_test_info['cash'] = market_info['cash']

        # 最新持仓
        position_set = UpSimutradeLatestPositioninfo.objects.filter(tradeid=deal_id).using('deal')
        position_list = []
        for position in position_set.values():
            position_info = {'stock_code': position['stockcode'], 'stock_name': position['stockname'],
                             'close': position['close'], 'quantity': position['quantity'],
                             'market_value': position['marketvalue'], 'return_field': position['return_field']}

            position_list.append(position_info)

        back_test_info['position_list'] = position_list

        # 收益详情用来画图
        deal_info = UpSimutradeBktestSumInfo.objects.using('deal').get(tradeid=deal_id)
        back_test_info['total_return'] = deal_info.totalreturn * 100
        back_test_info['annual_return'] = deal_info.myannualreturn * 100
        back_test_info['benchmark'] = deal_info.benchmark * 100
        back_test_info['benchmark_annual_return'] = deal_info.benchmarkannualreturn * 100
        back_test_info['sharpe'] = deal_info.sharpe
        back_test_info['max_drew_down'] = deal_info.maxdrewdown

        return back_test_info

    except Exception as e:
        # print str(e)
        return back_test_info


# 获得需要画图的收益详情
def get_deal_return_chart_detail(request):
    try:
        deal_id = request.session['deal_id']

        temp_return_list = []
        temp_benchmark_list = []
        query_set = BktestResultAnalyzeDtl.objects.filter(tradeid=deal_id).using('deal')
        for item in query_set.values():
            timeStamp = int(time.mktime(item['date'].timetuple())) * 1000
            temp_return_list.append([timeStamp, item['totalreturn'] * 100])
            temp_benchmark_list.append([timeStamp, item['benchmark'] * 100])

        result_dict = {'totalReturnList': temp_return_list, 'benchmarkReturnList': temp_benchmark_list}
        return result_dict

    except Exception as e:
        print str(e)
        return None


# 终止当前交易
def stop_deal(request):
    try:
        deal_id = request.session['deal_id']
        query = UpQuantSimutradeStrategylist.objects.get(tradeid=deal_id)
        query.status = 1
        query.enddate = datetime.datetime.today()
        query.save()
        return {'state': '0'}

    except Exception as e:
        return {'state': str(e)}


# 修改交易名称
def change_deal_name(request):
    try:
        deal_id = request.session['deal_id']
        src_deal_name = request.session['deal_name']

        data_dict = eval(request.body)
        dest_deal_name = data_dict['deal_name']
        if src_deal_name == dest_deal_name:
            return {'state': '0'}
        request.session['deal_name'] = dest_deal_name

        query = UpQuantSimutradeStrategylist.objects.get(tradeid=deal_id)
        query.tradename = dest_deal_name
        query.save()

    except Exception as e:
        return {'state': str(e)}
